package category

import (
	"context"
	"encoding/json"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"google.golang.org/protobuf/types/known/emptypb"
	"net/http"
	"strconv"
	"web/goods/api"
	"web/goods/forms"
	"web/goods/global"
	"web/goods/proto"
)

// 创建商品分类
func CreateCategory(ctx *gin.Context) {
	f := new(forms.CreateCategoryForm)
	if err := ctx.ShouldBind(&f); err != nil {
		api.HandleValidatorError(ctx, err)
		return
	}

	rsp, err := global.GoodsSrvClient.CreateCategory(context.Background(), &proto.CategoryInfoRequest{
		Name:           f.Name,
		ParentCategory: f.Parent,
		Level:          f.Level,
		IsTab:          *f.IsTab,
	})
	if err != nil {
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	// 如果rsp对应的protobuf定义中json标签的解析结果与接口文档中对应的字段名不一致，
	// 例如json解析结果是isTab，但是接口文档中的字段是is_tab，那么这里就有必要像下方代码一样做字段名的转换
	ctx.JSON(http.StatusOK, gin.H{
		"id":              rsp.Id,
		"name":            rsp.Name,
		"parent_category": rsp.ParentCategory,
		"level":           rsp.Level,
		"is_tab":          rsp.IsTab,
	})
}

// 获取商品分类
func GetCategories(ctx *gin.Context) {
	c := global.GoodsSrvClient
	rsp, err := c.GetAllCategorysList(context.Background(), &emptypb.Empty{})
	if err != nil {
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, rsp.JsonData)
}

// 修改商品分类
func UpdateCategory(ctx *gin.Context) {
	idStr := ctx.Param("id")
	idInt, err := strconv.Atoi(idStr)
	if err != nil {
		zap.S().Error("strconv.Atoi：string转int类型发生错误")
		ctx.JSON(http.StatusNotFound, gin.H{
			"msg": "解析参数出错，请检查商品分类id参数",
		})
		return
	}

	raw, _ := ctx.GetRawData()
	f := new(forms.UpdateCategoryForm)
	json.Unmarshal(raw, &f)

	var isTab bool

	if f.IsTab == 1 {
		isTab = true
	}

	_, err = global.GoodsSrvClient.UpdateCategory(context.Background(), &proto.CategoryInfoRequest{
		Id:             int32(idInt),
		Name:           f.Name,
		ParentCategory: f.Parent,
		Level:          f.Level,
		IsTab:          isTab,
	})
	if err != nil {
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg": "修改成功",
	})
}

// 删除商品分类
func DeleteCategory(ctx *gin.Context) {
	idStr := ctx.Param("id")
	idInt, err := strconv.Atoi(idStr)
	if err != nil {
		zap.S().Error("strconv.Atoi：string转int类型发生错误")
		ctx.JSON(http.StatusNotFound, gin.H{
			"msg": "解析参数出错，请检查商品分类id参数",
		})
		return
	}

	_, err = global.GoodsSrvClient.DeleteCategory(context.Background(), &proto.DeleteCategoryRequest{
		Id: int32(idInt),
	})
	if err != nil {
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "删除成功",
	})
}

// 获取商品分类的详情
func GetCategoryInfo(ctx *gin.Context) {
	idStr := ctx.Param("id")
	idInt, err := strconv.Atoi(idStr)
	if err != nil {
		zap.S().Error("strconv.Atoi：string转int类型发生错误")
		ctx.JSON(http.StatusNotFound, gin.H{
			"msg": "解析参数出错，请检查商品分类id参数",
		})
		return
	}

	r, err := global.GoodsSrvClient.GetSubCategory(context.Background(), &proto.CategoryListRequest{
		Id: int32(idInt),
	})
	if err != nil {
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	subCategorys := make([]interface{}, 0)
	for _, v := range r.SubCategorys {
		subCategorys = append(subCategorys, gin.H{
			"id":              v.Id,
			"name":            v.Name,
			"parent_category": v.ParentCategory,
			"level":           v.Level,
		})
	}

	ctx.JSON(http.StatusOK, gin.H{
		"total":         r.Total,
		"info":          r.Info,
		"sub_categorys": subCategorys,
	})
}
